package net.ncraft.mc.easyframework.easygame.gamekits.inventorygui;

import lombok.Getter;
import lombok.Setter;
import org.bukkit.Bukkit;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DefaultInventoryGui implements InventoryGui, Listener {

    @Getter
    @Setter
    private JavaPlugin plugin;

    @Getter
    private Integer size;

    @Setter
    private InventoryAction onOpen;

    @Setter
    private InventoryAction onClose;

    @Getter
    @Setter
    private String title;

    @Setter
    @Getter
    private boolean enablePage = false;

    @Getter
    @Setter
    private int currentPage = 1;

    @Getter
    private final List<ItemElement> elements = new ArrayList<>();

    private final Map<Player, Inventory> inventories = new HashMap<>();


    public DefaultInventoryGui(Integer size, String title, JavaPlugin plugin) {
        this.size = size;
        this.plugin = plugin;
        this.title = title;
        plugin.getServer().getPluginManager().registerEvents(this, plugin);
    }

    @Override
    public void addElement(ItemElement element) {
        elements.add(element);
    }

    @Override
    public void addElements(List<ItemElement> elements) {
        this.elements.addAll(elements);
    }

    @Override
    public void refresh() {
        for (Player player : inventories.keySet()) {
            Inventory inventory = inventories.get(player);
            ItemStack[] itemStacks = new ItemStack[elements.size()];
            //按照优先级排序 越大越靠前
            elements.sort((o1, o2) -> o2.getPriority() - o1.getPriority());
            for (int i = 0; i < elements.size(); i++) {
                ItemElement element = elements.get(i);
                //判断当前位置是否有元素了
                if (inventory.getItem(element.getSlot()) == null) {
                    itemStacks[element.getSlot()] = element.getItem();
                }
            }
            inventory.setContents(itemStacks);
        }
    }

    @Override
    public void open(Player player) {
        Inventory inventory = Bukkit.createInventory(player, size, title);
        this.inventories.put(player, inventory);
        refresh();
        player.openInventory(inventory);

    }

    @EventHandler
    public void onInventoryClick(InventoryClickEvent event) {
        HumanEntity player = event.getWhoClicked();
        if (!(player instanceof Player)) return;
        if (!inventories.get(player).equals(event.getInventory())) return;
        ItemStack currentItem = event.getCurrentItem();
        if (currentItem != null) {
            for (ItemElement element : elements) {
                if (element.getItem().equals(currentItem)) {
                    if (element.getOnClick() != null) {
                        element.getOnClick().execute((Player) player, element);
                    }
                }
            }
        }
        event.setCancelled(true);
    }


    @EventHandler
    public void onInventoryClose(InventoryCloseEvent event) {
        HumanEntity player = event.getPlayer();
        if (!(player instanceof Player)) return;
        if (!inventories.get(player).equals(event.getInventory())) return;
        if (onOpen != null) {
            onClose.execute((Player) player, this);
        }
        inventories.remove(player);
        if (inventories.isEmpty()) {
           unregister();
        }
    }

    @EventHandler
    public void onInventoryOpen(InventoryOpenEvent event) {
        HumanEntity player = event.getPlayer();
        if (!(player instanceof Player)) return;
        if (!inventories.get(player).equals(event.getInventory())) return;
        if (onOpen != null) {
            onOpen.execute((Player) player, this);
            System.out.println("打开");
        }
    }


    private void unregister() {
        InventoryClickEvent.getHandlerList().unregister(this);
        InventoryOpenEvent.getHandlerList().unregister(this);
        InventoryCloseEvent.getHandlerList().unregister(this);
    }


}
